<h1 id="hello-world">Hello World</h1>
<p>##本章学习Qt的基本功能</p>
<h2 id="例1简单的窗口">例1，简单的窗口</h2>
<p>这个简单的小例子展示的是一个小窗口。但是我们可以在这个小窗口上面做很多事情，改变大小，最大化，最小化等，这需要很多代码才能实现。这在很多应用中很常见，没必要每次都要重写这部分代码，Qt已经提供了这些功能。PyQt5是一个高级的工具集合，相比使用低级的工具，能省略上百行代码。</p>
<div class="sourceCode" id="cb1"><pre><code class="language-python"><a class="sourceLine" id="cb1-1" data-line-number="1"><span class="co">#!/usr/bin/python3</span></a>
<a class="sourceLine" id="cb1-2" data-line-number="2"><span class="co"># -*- coding: utf-8 -*-</span></a>
<a class="sourceLine" id="cb1-3" data-line-number="3"></a>
<a class="sourceLine" id="cb1-4" data-line-number="4"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb1-5" data-line-number="5"><span class="co">ZetCode PyQt5 tutorial </span></a>
<a class="sourceLine" id="cb1-6" data-line-number="6"></a>
<a class="sourceLine" id="cb1-7" data-line-number="7"><span class="co">In this example, we create a simple</span></a>
<a class="sourceLine" id="cb1-8" data-line-number="8"><span class="co">window in PyQt5.</span></a>
<a class="sourceLine" id="cb1-9" data-line-number="9"></a>
<a class="sourceLine" id="cb1-10" data-line-number="10"><span class="co">author: Jan Bodnar</span></a>
<a class="sourceLine" id="cb1-11" data-line-number="11"><span class="co">website: zetcode.com </span></a>
<a class="sourceLine" id="cb1-12" data-line-number="12"><span class="co">Last edited: August 2017</span></a>
<a class="sourceLine" id="cb1-13" data-line-number="13"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb1-14" data-line-number="14"></a>
<a class="sourceLine" id="cb1-15" data-line-number="15"><span class="im">import</span> sys</a>
<a class="sourceLine" id="cb1-16" data-line-number="16"><span class="im">from</span> PyQt5.QtWidgets <span class="im">import</span> QApplication, QWidget</a>
<a class="sourceLine" id="cb1-17" data-line-number="17"></a>
<a class="sourceLine" id="cb1-18" data-line-number="18"></a>
<a class="sourceLine" id="cb1-19" data-line-number="19"><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">&#39;__main__&#39;</span>:</a>
<a class="sourceLine" id="cb1-20" data-line-number="20">    </a>
<a class="sourceLine" id="cb1-21" data-line-number="21">    app <span class="op">=</span> QApplication(sys.argv)</a>
<a class="sourceLine" id="cb1-22" data-line-number="22"></a>
<a class="sourceLine" id="cb1-23" data-line-number="23">    w <span class="op">=</span> QWidget()</a>
<a class="sourceLine" id="cb1-24" data-line-number="24">    w.resize(<span class="dv">250</span>, <span class="dv">150</span>)</a>
<a class="sourceLine" id="cb1-25" data-line-number="25">    w.move(<span class="dv">300</span>, <span class="dv">300</span>)</a>
<a class="sourceLine" id="cb1-26" data-line-number="26">    w.setWindowTitle(<span class="st">&#39;Simple&#39;</span>)</a>
<a class="sourceLine" id="cb1-27" data-line-number="27">    w.show()</a>
<a class="sourceLine" id="cb1-28" data-line-number="28">    </a>
<a class="sourceLine" id="cb1-29" data-line-number="29">    sys.exit(app.exec_())</a></code></pre></div>
<p>运行上面的代码，能展示出一个小窗口。</p>
<pre><code class="language-python">import sys
from PyQt5.QtWidgets import QApplication, QWidget</code></pre>
<p>这里引入了PyQt5.QtWidgets模块，这个模块包含了基本的组件。</p>
<pre><code class="language-python">app = QApplication(sys.argv)</code></pre>
<p>每个PyQt5应用都必须创建一个应用对象。sys.argv是一组命令行参数的列表。Python可以在shell里运行，这个参数提供对脚本控制的功能。</p>
<pre><code class="language-python">w = QWidget()</code></pre>
<p>QWidge控件是一个用户界面的基本控件，它提供了基本的应用构造器。默认情况下，构造器是没有父级的，没有父级的构造器被称为窗口（window）。</p>
<pre><code class="language-python">w.resize(250, 150)</code></pre>
<p>resize()方法能改变控件的大小，这里的意思是窗口宽250px，高150px。</p>
<pre><code class="language-python">w.move(300, 300)</code></pre>
<p>move()是修改控件位置的的方法。它把控件放置到屏幕坐标的(300, 300)的位置。注：屏幕坐标系的原点是屏幕的左上角。</p>
<pre><code class="language-python">w.setWindowTitle(&#39;Simple&#39;)</code></pre>
<p>我们给这个窗口添加了一个标题，标题在标题栏展示（虽然这看起来是一句废话，但是后面还有各种栏，还是要注意一下，多了就蒙了）。</p>
<pre><code class="language-python">w.show()</code></pre>
<p>show()能让控件在桌面上显示出来。控件在内存里创建，之后才能在显示器上显示出来。</p>
<pre><code class="language-python">sys.exit(app.exec_())</code></pre>
<p>最后，我们进入了应用的主循环中，事件处理器这个时候开始工作。主循环从窗口上接收事件，并把事件传入到派发到应用控件里。当调用<code>exit()</code>方法或直接销毁主控件时，主循环就会结束。<code>sys.exit()</code>方法能确保主循环安全退出。外部环境能通知主控件怎么结束。</p>
<p><code>exec_()</code>之所以有个下划线，是因为<code>exec</code>是一个Python的关键字。</p>
<p>程序预览：</p>
<figure>
<img class="whitelist" src="docs/PyQt5/images/1-simple.png" alt="simple" />
</figure>
<h2 id="例2带窗口图标">例2，带窗口图标</h2>
<p>窗口图标通常是显示在窗口的左上角，标题栏的最左边。下面的例子就是怎么用PyQt5创建一个这样的窗口。</p>
<p>在某些环境下，图标显示不出来。如果你遇到了这个问题，看我在Stackoverfolw的<a href="https://stackoverflow.com/questions/44080247/pyqt5-does-now-show-icons/45439678#45439678">回答</a></p>
<div class="sourceCode" id="cb10"><pre><code class="language-python"><a class="sourceLine" id="cb10-1" data-line-number="1"><span class="co">#!/usr/bin/python3</span></a>
<a class="sourceLine" id="cb10-2" data-line-number="2"><span class="co"># -*- coding: utf-8 -*-</span></a>
<a class="sourceLine" id="cb10-3" data-line-number="3"></a>
<a class="sourceLine" id="cb10-4" data-line-number="4"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb10-5" data-line-number="5"><span class="co">ZetCode PyQt5 tutorial </span></a>
<a class="sourceLine" id="cb10-6" data-line-number="6"></a>
<a class="sourceLine" id="cb10-7" data-line-number="7"><span class="co">This example shows an icon</span></a>
<a class="sourceLine" id="cb10-8" data-line-number="8"><span class="co">in the titlebar of the window.</span></a>
<a class="sourceLine" id="cb10-9" data-line-number="9"></a>
<a class="sourceLine" id="cb10-10" data-line-number="10"><span class="co">Author: Jan Bodnar</span></a>
<a class="sourceLine" id="cb10-11" data-line-number="11"><span class="co">Website: zetcode.com </span></a>
<a class="sourceLine" id="cb10-12" data-line-number="12"><span class="co">Last edited: August 2017</span></a>
<a class="sourceLine" id="cb10-13" data-line-number="13"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb10-14" data-line-number="14"></a>
<a class="sourceLine" id="cb10-15" data-line-number="15"><span class="im">import</span> sys</a>
<a class="sourceLine" id="cb10-16" data-line-number="16"><span class="im">from</span> PyQt5.QtWidgets <span class="im">import</span> QApplication, QWidget</a>
<a class="sourceLine" id="cb10-17" data-line-number="17"><span class="im">from</span> PyQt5.QtGui <span class="im">import</span> QIcon</a>
<a class="sourceLine" id="cb10-18" data-line-number="18"></a>
<a class="sourceLine" id="cb10-19" data-line-number="19"></a>
<a class="sourceLine" id="cb10-20" data-line-number="20"><span class="kw">class</span> Example(QWidget):</a>
<a class="sourceLine" id="cb10-21" data-line-number="21">    </a>
<a class="sourceLine" id="cb10-22" data-line-number="22">    <span class="kw">def</span> <span class="fu">__init__</span>(<span class="va">self</span>):</a>
<a class="sourceLine" id="cb10-23" data-line-number="23">        <span class="bu">super</span>().<span class="fu">__init__</span>()</a>
<a class="sourceLine" id="cb10-24" data-line-number="24">        </a>
<a class="sourceLine" id="cb10-25" data-line-number="25">        <span class="va">self</span>.initUI()</a>
<a class="sourceLine" id="cb10-26" data-line-number="26">        </a>
<a class="sourceLine" id="cb10-27" data-line-number="27">        </a>
<a class="sourceLine" id="cb10-28" data-line-number="28">    <span class="kw">def</span> initUI(<span class="va">self</span>):</a>
<a class="sourceLine" id="cb10-29" data-line-number="29">        </a>
<a class="sourceLine" id="cb10-30" data-line-number="30">        <span class="va">self</span>.setGeometry(<span class="dv">300</span>, <span class="dv">300</span>, <span class="dv">300</span>, <span class="dv">220</span>)</a>
<a class="sourceLine" id="cb10-31" data-line-number="31">        <span class="va">self</span>.setWindowTitle(<span class="st">&#39;Icon&#39;</span>)</a>
<a class="sourceLine" id="cb10-32" data-line-number="32">        <span class="va">self</span>.setWindowIcon(QIcon(<span class="st">&#39;web.png&#39;</span>))        </a>
<a class="sourceLine" id="cb10-33" data-line-number="33">    </a>
<a class="sourceLine" id="cb10-34" data-line-number="34">        <span class="va">self</span>.show()</a>
<a class="sourceLine" id="cb10-35" data-line-number="35">        </a>
<a class="sourceLine" id="cb10-36" data-line-number="36">        </a>
<a class="sourceLine" id="cb10-37" data-line-number="37"><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">&#39;__main__&#39;</span>:</a>
<a class="sourceLine" id="cb10-38" data-line-number="38">    </a>
<a class="sourceLine" id="cb10-39" data-line-number="39">    app <span class="op">=</span> QApplication(sys.argv)</a>
<a class="sourceLine" id="cb10-40" data-line-number="40">    ex <span class="op">=</span> Example()</a>
<a class="sourceLine" id="cb10-41" data-line-number="41">    sys.exit(app.exec_())</a></code></pre></div>
<p>前一个例子是使用的<a href="https://www.wikiwand.com/zh/%E8%BF%87%E7%A8%8B%E5%BC%8F%E7%BC%96%E7%A8%8B">过程式编程</a>。Python还支持<a href="https://www.wikiwand.com/zh/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1">面向对象</a>的编程：</p>
<pre><code class="language-python">class Example(QWidget):
    
    def __init__(self):
        super().__init__()
        ...</code></pre>
<p>面向对象编程最重要的三个部分是类(class)、数据和方法。我们创建了一个类的调用，这个类继承自<code>QWidget</code>。这就意味着，我们调用了两个构造器，一个是这个类本身的，一个是这个类继承的。<code>super()</code>构造器方法返回父级的对象。<code>__init__()</code>方法是构造器的一个方法。</p>
<pre><code class="language-python">self.initUI() </code></pre>
<p>使用<code>initUI()</code>方法创建一个GUI。</p>
<pre><code class="language-python"># 自己准备一个web.png
self.setGeometry(300, 300, 300, 220)
self.setWindowTitle(&#39;Icon&#39;)
self.setWindowIcon(QIcon(&#39;web.png&#39;))  </code></pre>
<p>上面的三个方法都继承自<code>QWidget</code>类。<code>setGeometry()</code>有两个作用：把窗口放到屏幕上并且设置窗口大小。参数分别代表屏幕坐标的x、y和窗口大小的宽、高。也就是说这个方法是<code>resize()</code>和<code>move()</code>的合体。最后一个方法是添加了图标。先创建一个QIcon对象，然后接受一个路径作为参数显示图标。</p>
<pre><code class="language-python">if __name__ == &#39;__main__&#39;:
    
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())</code></pre>
<p>应用和示例的对象创立，主循环开始。</p>
<p>程序预览：</p>
<figure>
<img class="whitelist" src="docs/PyQt5/images/1-icon.png" alt="icon" />
</figure>
<h2 id="例3提示框">例3，提示框</h2>
<div class="sourceCode" id="cb15"><pre><code class="language-python"><a class="sourceLine" id="cb15-1" data-line-number="1"><span class="co">#!/usr/bin/python3</span></a>
<a class="sourceLine" id="cb15-2" data-line-number="2"><span class="co"># -*- coding: utf-8 -*-</span></a>
<a class="sourceLine" id="cb15-3" data-line-number="3"></a>
<a class="sourceLine" id="cb15-4" data-line-number="4"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb15-5" data-line-number="5"><span class="co">ZetCode PyQt5 tutorial </span></a>
<a class="sourceLine" id="cb15-6" data-line-number="6"></a>
<a class="sourceLine" id="cb15-7" data-line-number="7"><span class="co">This example shows a tooltip on </span></a>
<a class="sourceLine" id="cb15-8" data-line-number="8"><span class="co">a window and a button.</span></a>
<a class="sourceLine" id="cb15-9" data-line-number="9"></a>
<a class="sourceLine" id="cb15-10" data-line-number="10"><span class="co">Author: Jan Bodnar</span></a>
<a class="sourceLine" id="cb15-11" data-line-number="11"><span class="co">Website: zetcode.com </span></a>
<a class="sourceLine" id="cb15-12" data-line-number="12"><span class="co">Last edited: August 2017</span></a>
<a class="sourceLine" id="cb15-13" data-line-number="13"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb15-14" data-line-number="14"></a>
<a class="sourceLine" id="cb15-15" data-line-number="15"><span class="im">import</span> sys</a>
<a class="sourceLine" id="cb15-16" data-line-number="16"><span class="im">from</span> PyQt5.QtWidgets <span class="im">import</span> (QWidget, QToolTip, </a>
<a class="sourceLine" id="cb15-17" data-line-number="17">    QPushButton, QApplication)</a>
<a class="sourceLine" id="cb15-18" data-line-number="18"><span class="im">from</span> PyQt5.QtGui <span class="im">import</span> QFont    </a>
<a class="sourceLine" id="cb15-19" data-line-number="19"></a>
<a class="sourceLine" id="cb15-20" data-line-number="20"></a>
<a class="sourceLine" id="cb15-21" data-line-number="21"><span class="kw">class</span> Example(QWidget):</a>
<a class="sourceLine" id="cb15-22" data-line-number="22">    </a>
<a class="sourceLine" id="cb15-23" data-line-number="23">    <span class="kw">def</span> <span class="fu">__init__</span>(<span class="va">self</span>):</a>
<a class="sourceLine" id="cb15-24" data-line-number="24">        <span class="bu">super</span>().<span class="fu">__init__</span>()</a>
<a class="sourceLine" id="cb15-25" data-line-number="25">        </a>
<a class="sourceLine" id="cb15-26" data-line-number="26">        <span class="va">self</span>.initUI()</a>
<a class="sourceLine" id="cb15-27" data-line-number="27">        </a>
<a class="sourceLine" id="cb15-28" data-line-number="28">        </a>
<a class="sourceLine" id="cb15-29" data-line-number="29">    <span class="kw">def</span> initUI(<span class="va">self</span>):</a>
<a class="sourceLine" id="cb15-30" data-line-number="30">        </a>
<a class="sourceLine" id="cb15-31" data-line-number="31">        QToolTip.setFont(QFont(<span class="st">&#39;SansSerif&#39;</span>, <span class="dv">10</span>))</a>
<a class="sourceLine" id="cb15-32" data-line-number="32">        </a>
<a class="sourceLine" id="cb15-33" data-line-number="33">        <span class="va">self</span>.setToolTip(<span class="st">&#39;This is a &lt;b&gt;QWidget&lt;/b&gt; widget&#39;</span>)</a>
<a class="sourceLine" id="cb15-34" data-line-number="34">        </a>
<a class="sourceLine" id="cb15-35" data-line-number="35">        btn <span class="op">=</span> QPushButton(<span class="st">&#39;Button&#39;</span>, <span class="va">self</span>)</a>
<a class="sourceLine" id="cb15-36" data-line-number="36">        btn.setToolTip(<span class="st">&#39;This is a &lt;b&gt;QPushButton&lt;/b&gt; widget&#39;</span>)</a>
<a class="sourceLine" id="cb15-37" data-line-number="37">        btn.resize(btn.sizeHint())</a>
<a class="sourceLine" id="cb15-38" data-line-number="38">        btn.move(<span class="dv">50</span>, <span class="dv">50</span>)       </a>
<a class="sourceLine" id="cb15-39" data-line-number="39">        </a>
<a class="sourceLine" id="cb15-40" data-line-number="40">        <span class="va">self</span>.setGeometry(<span class="dv">300</span>, <span class="dv">300</span>, <span class="dv">300</span>, <span class="dv">200</span>)</a>
<a class="sourceLine" id="cb15-41" data-line-number="41">        <span class="va">self</span>.setWindowTitle(<span class="st">&#39;Tooltips&#39;</span>)    </a>
<a class="sourceLine" id="cb15-42" data-line-number="42">        <span class="va">self</span>.show()</a>
<a class="sourceLine" id="cb15-43" data-line-number="43">        </a>
<a class="sourceLine" id="cb15-44" data-line-number="44">        </a>
<a class="sourceLine" id="cb15-45" data-line-number="45"><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">&#39;__main__&#39;</span>:</a>
<a class="sourceLine" id="cb15-46" data-line-number="46">    </a>
<a class="sourceLine" id="cb15-47" data-line-number="47">    app <span class="op">=</span> QApplication(sys.argv)</a>
<a class="sourceLine" id="cb15-48" data-line-number="48">    ex <span class="op">=</span> Example()</a>
<a class="sourceLine" id="cb15-49" data-line-number="49">    sys.exit(app.exec_())</a></code></pre></div>
<p>在这个例子中，我们为应用创建了一个提示框。</p>
<pre><code class="language-python">QToolTip.setFont(QFont(&#39;SansSerif&#39;, 10))</code></pre>
<p>这个静态方法设置了提示框的字体，我们使用了10px的SansSerif字体。</p>
<pre><code class="language-python">self.setToolTip(&#39;This is a &lt;b&gt;QWidget&lt;/b&gt; widget&#39;)</code></pre>
<p>调用<code>setTooltip()</code>创建提示框可以使用富文本格式的内容。</p>
<pre><code class="language-python">btn = QPushButton(&#39;Button&#39;, self)
btn.setToolTip(&#39;This is a &lt;b&gt;QPushButton&lt;/b&gt; widget&#39;)</code></pre>
<p>创建一个按钮，并且为按钮添加了一个提示框。</p>
<pre><code class="language-python">btn.resize(btn.sizeHint())
btn.move(50, 50)</code></pre>
<p>调整按钮大小，并让按钮在屏幕上显示出来，<code>sizeHint()</code>方法提供了一个默认的按钮大小。</p>
<p>程序预览：</p>
<figure>
<img class="whitelist" src="docs/PyQt5/images/1-tooltips.png" alt="tooltip" />
</figure>
<h2 id="例4关闭窗口">例4，关闭窗口</h2>
<p>关闭一个窗口最直观的方式就是点击标题栏的那个叉，这个例子里，我们展示的是如何用程序关闭一个窗口。这里我们将接触到一点single和slots的知识。</p>
<p>本例使用的是QPushButton组件类。</p>
<pre><code class="language-python">QPushButton(string text, QWidget parent = None)</code></pre>
<p><code>text</code>参数是想要显示的按钮名称，<code>parent</code>参数是放在按钮上的组件，在我们的 例子里，这个参数是<code>QWidget</code>。应用中的组件都是一层一层（继承而来的？）的，在这个层里，大部分的组件都有自己的父级，没有父级的组件，是顶级的窗口。</p>
<div class="sourceCode" id="cb21"><pre><code class="language-python"><a class="sourceLine" id="cb21-1" data-line-number="1"><span class="co">#!/usr/bin/python3</span></a>
<a class="sourceLine" id="cb21-2" data-line-number="2"><span class="co"># -*- coding: utf-8 -*-</span></a>
<a class="sourceLine" id="cb21-3" data-line-number="3"></a>
<a class="sourceLine" id="cb21-4" data-line-number="4"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb21-5" data-line-number="5"><span class="co">ZetCode PyQt5 tutorial </span></a>
<a class="sourceLine" id="cb21-6" data-line-number="6"></a>
<a class="sourceLine" id="cb21-7" data-line-number="7"><span class="co">This program creates a quit</span></a>
<a class="sourceLine" id="cb21-8" data-line-number="8"><span class="co">button. When we press the button,</span></a>
<a class="sourceLine" id="cb21-9" data-line-number="9"><span class="co">the application terminates. </span></a>
<a class="sourceLine" id="cb21-10" data-line-number="10"></a>
<a class="sourceLine" id="cb21-11" data-line-number="11"><span class="co">Author: Jan Bodnar</span></a>
<a class="sourceLine" id="cb21-12" data-line-number="12"><span class="co">Website: zetcode.com </span></a>
<a class="sourceLine" id="cb21-13" data-line-number="13"><span class="co">Last edited: August 2017</span></a>
<a class="sourceLine" id="cb21-14" data-line-number="14"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb21-15" data-line-number="15"></a>
<a class="sourceLine" id="cb21-16" data-line-number="16"><span class="im">import</span> sys</a>
<a class="sourceLine" id="cb21-17" data-line-number="17"><span class="im">from</span> PyQt5.QtWidgets <span class="im">import</span> QWidget, QPushButton, QApplication</a>
<a class="sourceLine" id="cb21-18" data-line-number="18"><span class="im">from</span> PyQt5.QtCore <span class="im">import</span> QCoreApplication</a>
<a class="sourceLine" id="cb21-19" data-line-number="19"></a>
<a class="sourceLine" id="cb21-20" data-line-number="20"></a>
<a class="sourceLine" id="cb21-21" data-line-number="21"><span class="kw">class</span> Example(QWidget):</a>
<a class="sourceLine" id="cb21-22" data-line-number="22">    </a>
<a class="sourceLine" id="cb21-23" data-line-number="23">    <span class="kw">def</span> <span class="fu">__init__</span>(<span class="va">self</span>):</a>
<a class="sourceLine" id="cb21-24" data-line-number="24">        <span class="bu">super</span>().<span class="fu">__init__</span>()</a>
<a class="sourceLine" id="cb21-25" data-line-number="25">        </a>
<a class="sourceLine" id="cb21-26" data-line-number="26">        <span class="va">self</span>.initUI()</a>
<a class="sourceLine" id="cb21-27" data-line-number="27">        </a>
<a class="sourceLine" id="cb21-28" data-line-number="28">        </a>
<a class="sourceLine" id="cb21-29" data-line-number="29">    <span class="kw">def</span> initUI(<span class="va">self</span>):               </a>
<a class="sourceLine" id="cb21-30" data-line-number="30">        </a>
<a class="sourceLine" id="cb21-31" data-line-number="31">        qbtn <span class="op">=</span> QPushButton(<span class="st">&#39;Quit&#39;</span>, <span class="va">self</span>)</a>
<a class="sourceLine" id="cb21-32" data-line-number="32">        qbtn.clicked.<span class="ex">connect</span>(QCoreApplication.instance().quit)</a>
<a class="sourceLine" id="cb21-33" data-line-number="33">        qbtn.resize(qbtn.sizeHint())</a>
<a class="sourceLine" id="cb21-34" data-line-number="34">        qbtn.move(<span class="dv">50</span>, <span class="dv">50</span>)       </a>
<a class="sourceLine" id="cb21-35" data-line-number="35">        </a>
<a class="sourceLine" id="cb21-36" data-line-number="36">        <span class="va">self</span>.setGeometry(<span class="dv">300</span>, <span class="dv">300</span>, <span class="dv">250</span>, <span class="dv">150</span>)</a>
<a class="sourceLine" id="cb21-37" data-line-number="37">        <span class="va">self</span>.setWindowTitle(<span class="st">&#39;Quit button&#39;</span>)    </a>
<a class="sourceLine" id="cb21-38" data-line-number="38">        <span class="va">self</span>.show()</a>
<a class="sourceLine" id="cb21-39" data-line-number="39">        </a>
<a class="sourceLine" id="cb21-40" data-line-number="40">        </a>
<a class="sourceLine" id="cb21-41" data-line-number="41"><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">&#39;__main__&#39;</span>:</a>
<a class="sourceLine" id="cb21-42" data-line-number="42">    </a>
<a class="sourceLine" id="cb21-43" data-line-number="43">    app <span class="op">=</span> QApplication(sys.argv)</a>
<a class="sourceLine" id="cb21-44" data-line-number="44">    ex <span class="op">=</span> Example()</a>
<a class="sourceLine" id="cb21-45" data-line-number="45">    sys.exit(app.exec_())</a></code></pre></div>
<p>这里创建了一个点击之后就退出窗口的按钮。</p>
<pre><code class="language-python">from PyQt5.QtCore import QCoreApplication</code></pre>
<p>程序需要<code>QtCore</code>对象。</p>
<pre><code class="language-python">qbtn = QPushButton(&#39;Quit&#39;, self)</code></pre>
<p>创建一个继承自<code>QPushButton</code>的按钮。第一个参数是按钮的文本，第二个参数是按钮的父级组件，这个例子中，父级组件就是我们创建的继承自<code>Qwidget</code>的<code>Example</code>类。</p>
<pre><code class="language-python">qbtn.clicked.connect(QCoreApplication.instance().quit)</code></pre>
<p>事件传递系统在PyQt5内建的single和slot机制里面。点击按钮之后，信号会被捕捉并给出既定的反应。<code>QCoreApplication</code>包含了事件的主循环，它能添加和删除所有的事件，<code>instance()</code>创建了一个它的实例。<code>QCoreApplication</code>是在<code>QApplication</code>里创建的。 点击事件和能终止进程并退出应用的quit函数绑定在了一起。在发送者和接受者之间建立了通讯，发送者就是按钮，接受者就是应用对象。</p>
<p>程序预览：</p>
<figure>
<img class="whitelist" src="docs/PyQt5/images/1-quitbutton.png" alt="quitbutton" />
</figure>
<h2 id="例5消息盒子">例5，消息盒子</h2>
<p>默认情况下，我们点击标题栏的×按钮，QWidget就会关闭。但是有时候，我们修改默认行为。比如，如果我们打开的是一个文本编辑器，并且做了一些修改，我们就会想在关闭按钮的时候让用户进一步确认操作。</p>
<div class="sourceCode" id="cb25"><pre><code class="language-python"><a class="sourceLine" id="cb25-1" data-line-number="1"><span class="co">#!/usr/bin/python3</span></a>
<a class="sourceLine" id="cb25-2" data-line-number="2"><span class="co"># -*- coding: utf-8 -*-</span></a>
<a class="sourceLine" id="cb25-3" data-line-number="3"></a>
<a class="sourceLine" id="cb25-4" data-line-number="4"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb25-5" data-line-number="5"><span class="co">ZetCode PyQt5 tutorial </span></a>
<a class="sourceLine" id="cb25-6" data-line-number="6"></a>
<a class="sourceLine" id="cb25-7" data-line-number="7"><span class="co">This program shows a confirmation </span></a>
<a class="sourceLine" id="cb25-8" data-line-number="8"><span class="co">message box when we click on the close</span></a>
<a class="sourceLine" id="cb25-9" data-line-number="9"><span class="co">button of the application window. </span></a>
<a class="sourceLine" id="cb25-10" data-line-number="10"></a>
<a class="sourceLine" id="cb25-11" data-line-number="11"><span class="co">Author: Jan Bodnar</span></a>
<a class="sourceLine" id="cb25-12" data-line-number="12"><span class="co">Website: zetcode.com </span></a>
<a class="sourceLine" id="cb25-13" data-line-number="13"><span class="co">Last edited: August 2017</span></a>
<a class="sourceLine" id="cb25-14" data-line-number="14"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb25-15" data-line-number="15"></a>
<a class="sourceLine" id="cb25-16" data-line-number="16"><span class="im">import</span> sys</a>
<a class="sourceLine" id="cb25-17" data-line-number="17"><span class="im">from</span> PyQt5.QtWidgets <span class="im">import</span> QWidget, QMessageBox, QApplication</a>
<a class="sourceLine" id="cb25-18" data-line-number="18"></a>
<a class="sourceLine" id="cb25-19" data-line-number="19"></a>
<a class="sourceLine" id="cb25-20" data-line-number="20"><span class="kw">class</span> Example(QWidget):</a>
<a class="sourceLine" id="cb25-21" data-line-number="21">    </a>
<a class="sourceLine" id="cb25-22" data-line-number="22">    <span class="kw">def</span> <span class="fu">__init__</span>(<span class="va">self</span>):</a>
<a class="sourceLine" id="cb25-23" data-line-number="23">        <span class="bu">super</span>().<span class="fu">__init__</span>()</a>
<a class="sourceLine" id="cb25-24" data-line-number="24">        </a>
<a class="sourceLine" id="cb25-25" data-line-number="25">        <span class="va">self</span>.initUI()</a>
<a class="sourceLine" id="cb25-26" data-line-number="26">        </a>
<a class="sourceLine" id="cb25-27" data-line-number="27">        </a>
<a class="sourceLine" id="cb25-28" data-line-number="28">    <span class="kw">def</span> initUI(<span class="va">self</span>):               </a>
<a class="sourceLine" id="cb25-29" data-line-number="29">        </a>
<a class="sourceLine" id="cb25-30" data-line-number="30">        <span class="va">self</span>.setGeometry(<span class="dv">300</span>, <span class="dv">300</span>, <span class="dv">250</span>, <span class="dv">150</span>)        </a>
<a class="sourceLine" id="cb25-31" data-line-number="31">        <span class="va">self</span>.setWindowTitle(<span class="st">&#39;Message box&#39;</span>)    </a>
<a class="sourceLine" id="cb25-32" data-line-number="32">        <span class="va">self</span>.show()</a>
<a class="sourceLine" id="cb25-33" data-line-number="33">        </a>
<a class="sourceLine" id="cb25-34" data-line-number="34">        </a>
<a class="sourceLine" id="cb25-35" data-line-number="35">    <span class="kw">def</span> closeEvent(<span class="va">self</span>, event):</a>
<a class="sourceLine" id="cb25-36" data-line-number="36">        </a>
<a class="sourceLine" id="cb25-37" data-line-number="37">        reply <span class="op">=</span> QMessageBox.question(<span class="va">self</span>, <span class="st">&#39;Message&#39;</span>,</a>
<a class="sourceLine" id="cb25-38" data-line-number="38">            <span class="st">&quot;Are you sure to quit?&quot;</span>, QMessageBox.Yes <span class="op">|</span> </a>
<a class="sourceLine" id="cb25-39" data-line-number="39">            QMessageBox.No, QMessageBox.No)</a>
<a class="sourceLine" id="cb25-40" data-line-number="40"></a>
<a class="sourceLine" id="cb25-41" data-line-number="41">        <span class="cf">if</span> reply <span class="op">==</span> QMessageBox.Yes:</a>
<a class="sourceLine" id="cb25-42" data-line-number="42">            event.accept()</a>
<a class="sourceLine" id="cb25-43" data-line-number="43">        <span class="cf">else</span>:</a>
<a class="sourceLine" id="cb25-44" data-line-number="44">            event.ignore()        </a>
<a class="sourceLine" id="cb25-45" data-line-number="45">        </a>
<a class="sourceLine" id="cb25-46" data-line-number="46">        </a>
<a class="sourceLine" id="cb25-47" data-line-number="47"><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">&#39;__main__&#39;</span>:</a>
<a class="sourceLine" id="cb25-48" data-line-number="48">    </a>
<a class="sourceLine" id="cb25-49" data-line-number="49">    app <span class="op">=</span> QApplication(sys.argv)</a>
<a class="sourceLine" id="cb25-50" data-line-number="50">    ex <span class="op">=</span> Example()</a>
<a class="sourceLine" id="cb25-51" data-line-number="51">    sys.exit(app.exec_())</a></code></pre></div>
<p>如果关闭QWidget，就会产生一个QCloseEvent。改变控件的默认行为，就是替换掉默认的事件处理。</p>
<pre><code class="language-python">reply = QMessageBox.question(self, &#39;Message&#39;,
    &quot;Are you sure to quit?&quot;, QMessageBox.Yes | 
    QMessageBox.No, QMessageBox.No)</code></pre>
<p>我们创建了一个消息框，上面有俩按钮：Yes和No.第一个字符串显示在消息框的标题栏，第二个字符串显示在对话框，第三个参数是消息框的俩按钮，最后一个参数是默认按钮，这个按钮是默认选中的。返回值在变量<code>reply</code>里。</p>
<pre><code class="language-python">if reply == QtGui.QMessageBox.Yes:
    event.accept()
else:
    event.ignore()</code></pre>
<p>这里判断返回值，如果点击的是Yes按钮，我们就关闭组件和应用，否者就忽略关闭事件。</p>
<p>程序预览：</p>
<figure>
<img class="whitelist" src="docs/PyQt5/images/1-messagebox.png" alt="messagebox" />
</figure>
<h2 id="例6窗口居中">例6，窗口居中</h2>
<div class="sourceCode" id="cb28"><pre><code class="language-python"><a class="sourceLine" id="cb28-1" data-line-number="1"><span class="co">#!/usr/bin/python3</span></a>
<a class="sourceLine" id="cb28-2" data-line-number="2"><span class="co"># -*- coding: utf-8 -*-</span></a>
<a class="sourceLine" id="cb28-3" data-line-number="3"></a>
<a class="sourceLine" id="cb28-4" data-line-number="4"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb28-5" data-line-number="5"><span class="co">ZetCode PyQt5 tutorial </span></a>
<a class="sourceLine" id="cb28-6" data-line-number="6"></a>
<a class="sourceLine" id="cb28-7" data-line-number="7"><span class="co">This program centers a window </span></a>
<a class="sourceLine" id="cb28-8" data-line-number="8"><span class="co">on the screen. </span></a>
<a class="sourceLine" id="cb28-9" data-line-number="9"></a>
<a class="sourceLine" id="cb28-10" data-line-number="10"><span class="co">Author: Jan Bodnar</span></a>
<a class="sourceLine" id="cb28-11" data-line-number="11"><span class="co">Website: zetcode.com </span></a>
<a class="sourceLine" id="cb28-12" data-line-number="12"><span class="co">Last edited: August 2017</span></a>
<a class="sourceLine" id="cb28-13" data-line-number="13"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb28-14" data-line-number="14"></a>
<a class="sourceLine" id="cb28-15" data-line-number="15"><span class="im">import</span> sys</a>
<a class="sourceLine" id="cb28-16" data-line-number="16"><span class="im">from</span> PyQt5.QtWidgets <span class="im">import</span> QWidget, QDesktopWidget, QApplication</a>
<a class="sourceLine" id="cb28-17" data-line-number="17"></a>
<a class="sourceLine" id="cb28-18" data-line-number="18"></a>
<a class="sourceLine" id="cb28-19" data-line-number="19"><span class="kw">class</span> Example(QWidget):</a>
<a class="sourceLine" id="cb28-20" data-line-number="20">    </a>
<a class="sourceLine" id="cb28-21" data-line-number="21">    <span class="kw">def</span> <span class="fu">__init__</span>(<span class="va">self</span>):</a>
<a class="sourceLine" id="cb28-22" data-line-number="22">        <span class="bu">super</span>().<span class="fu">__init__</span>()</a>
<a class="sourceLine" id="cb28-23" data-line-number="23">        </a>
<a class="sourceLine" id="cb28-24" data-line-number="24">        <span class="va">self</span>.initUI()</a>
<a class="sourceLine" id="cb28-25" data-line-number="25">        </a>
<a class="sourceLine" id="cb28-26" data-line-number="26">        </a>
<a class="sourceLine" id="cb28-27" data-line-number="27">    <span class="kw">def</span> initUI(<span class="va">self</span>):               </a>
<a class="sourceLine" id="cb28-28" data-line-number="28">        </a>
<a class="sourceLine" id="cb28-29" data-line-number="29">        <span class="va">self</span>.resize(<span class="dv">250</span>, <span class="dv">150</span>)</a>
<a class="sourceLine" id="cb28-30" data-line-number="30">        <span class="va">self</span>.center()</a>
<a class="sourceLine" id="cb28-31" data-line-number="31">        </a>
<a class="sourceLine" id="cb28-32" data-line-number="32">        <span class="va">self</span>.setWindowTitle(<span class="st">&#39;Center&#39;</span>)    </a>
<a class="sourceLine" id="cb28-33" data-line-number="33">        <span class="va">self</span>.show()</a>
<a class="sourceLine" id="cb28-34" data-line-number="34">        </a>
<a class="sourceLine" id="cb28-35" data-line-number="35">        </a>
<a class="sourceLine" id="cb28-36" data-line-number="36">    <span class="kw">def</span> center(<span class="va">self</span>):</a>
<a class="sourceLine" id="cb28-37" data-line-number="37">        </a>
<a class="sourceLine" id="cb28-38" data-line-number="38">        qr <span class="op">=</span> <span class="va">self</span>.frameGeometry()</a>
<a class="sourceLine" id="cb28-39" data-line-number="39">        cp <span class="op">=</span> QDesktopWidget().availableGeometry().center()</a>
<a class="sourceLine" id="cb28-40" data-line-number="40">        qr.moveCenter(cp)</a>
<a class="sourceLine" id="cb28-41" data-line-number="41">        <span class="va">self</span>.move(qr.topLeft())</a>
<a class="sourceLine" id="cb28-42" data-line-number="42">        </a>
<a class="sourceLine" id="cb28-43" data-line-number="43">        </a>
<a class="sourceLine" id="cb28-44" data-line-number="44"><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">&#39;__main__&#39;</span>:</a>
<a class="sourceLine" id="cb28-45" data-line-number="45">    </a>
<a class="sourceLine" id="cb28-46" data-line-number="46">    app <span class="op">=</span> QApplication(sys.argv)</a>
<a class="sourceLine" id="cb28-47" data-line-number="47">    ex <span class="op">=</span> Example()</a>
<a class="sourceLine" id="cb28-48" data-line-number="48">    sys.exit(app.exec_())</a></code></pre></div>
<p><code>QtGui.QDesktopWidget</code>提供了用户的桌面信息，包括屏幕的大小。</p>
<pre><code class="language-python">self.center()</code></pre>
<p>这个方法是调用我们下面写的，实现对话框居中的方法。</p>
<pre><code class="language-python">qr = self.frameGeometry()</code></pre>
<p>得到了主窗口的大小。</p>
<pre><code class="language-python">cp = QDesktopWidget().availableGeometry().center()</code></pre>
<p>获取显示器的分辨率，然后得到中间点的位置。</p>
<pre><code class="language-python">qr.moveCenter(cp)</code></pre>
<p>然后把自己窗口的中心点放置到qr的中心点。</p>
<pre><code class="language-python">self.move(qr.topLeft())</code></pre>
<p>然后把窗口的坐上角的坐标设置为qr的矩形左上角的坐标，这样就把窗口居中了。</p>
<p>程序预览：</p>
<figure>
<img class="whitelist" src="docs/PyQt5/images/1-center.png" alt="center" />
</figure>
